package com.heima.article.service.impl;

import com.heima.article.entity.ApArticle;
import com.heima.article.service.ApArticleService;
import com.heima.article.service.FreemarkerService;
import com.heima.common.constants.message.Article2EsConstants;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.exception.LeadException;
import com.heima.common.util.JsonUtils;
import com.heima.file.service.MinioService;
import com.heima.model.media.dtos.WmNewsContentItem;
import com.heima.model.media.dtos.WmNewsResultDTO;
import freemarker.template.Configuration;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class FreemarkerServiceImpl implements FreemarkerService {


    @Autowired
    private Configuration configuration;

    @Autowired
    private MinioService minioService;

    @Autowired
    private ApArticleService articleService;

    @Autowired
    KafkaTemplate<String, String> kafkaTemplate;

    @Override
    @Async("taskExecutor")
    public void asyncCreateHtmlAndUploadMinio(Long articleId, WmNewsResultDTO dto) {
        // 这个代码不能删！因为是异步执行，可有会先于ap_article落库执行
        try{
            Thread.sleep(3000);
        }catch(Exception e){
            e.printStackTrace();
        }
        // 生成html
        String html = createHtml(dto);
        // 上传minio
        String url = upload2Minio(articleId, html);
        // 回填static_url
        updateArticleStaticUrl(articleId, url);
        // 发出kafka消息，通知搜索服务，插入到ES
        kafkaTemplate.send(Article2EsConstants.ARTICLE_2_ES_TOPIC, ""+articleId);
    }

    private String createHtml(WmNewsResultDTO dto){
        List<WmNewsContentItem> wmNewsContentItems = JsonUtils.toList(dto.getContent(), WmNewsContentItem.class);
        StringWriter writer = new StringWriter();
        try{
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("content", wmNewsContentItems);
            configuration.getTemplate("article.ftl").process(dataMap, writer);
        }catch(Exception e){
            log.error("模板渲染异常：{}", ExceptionUtils.getStackTrace(e));
            throw new LeadException(AppHttpCodeEnum.SERVER_ERROR);
        }
        String html = writer.toString();
        return html;
    }

    private String upload2Minio(Long articleId, String html){
        String filename = articleId + ".html";
        byte[] fileBytes = html.getBytes(StandardCharsets.UTF_8);
        String url = minioService.uploadHtmlFile("",filename , new ByteArrayInputStream(fileBytes));
        return url;
    }

    private void updateArticleStaticUrl(Long articleId, String url){
        ApArticle article = new ApArticle();
        article.setId(articleId);
        article.setStaticUrl(url);
        articleService.updateById(article);
    }
}
